home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1994 October / Macformat17.cdr / Shareware City / Developers / shutdown-fx-20-c / sfx startup app ƒ / Shell ƒ / prefs.c < prev    next >
Text File  |  1994-07-11  |  9KB  |  306 lines

  1. /**********************************************************************\
  2.  
  3. File:        prefs.c
  4.  
  5. Purpose:    This module handles creating/opening/closing/updating
  6.             the preference file, and copying the preference file
  7.             data into our globals (and back).
  8.  
  9. This program is free software; you can redistribute it and/or modify
  10. it under the terms of the GNU General Public License as published by
  11. the Free Software Foundation; either version 2 of the License, or
  12. (at your option) any later version.
  13.  
  14. This program is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. GNU General Public License for more details.
  18.  
  19. You should have received a copy of the GNU General Public License
  20. along with this program in a file named "GNU General Public License".
  21. If not, write to the Free Software Foundation, 675 Mass Ave,
  22. Cambridge, MA 02139, USA.
  23.  
  24. \**********************************************************************/
  25.  
  26. #include "Folders.h"
  27. #include "prefs.h"
  28. #include "environment.h"
  29. #include "program globals.h"
  30.  
  31. #define        PREFS_FILE_NAME            "\pShutdown FX prefs"
  32. #define        PREFS_TYPE                'pref'
  33. #define        PREFS_HEADER_VERSION    9
  34.  
  35. typedef struct
  36. {
  37.     short            maintopic;
  38.     short            subtopic;
  39.     char            onrestart;
  40.     char            onshutdown;
  41.     char            israndom;
  42.     char            unused;
  43.     short            moduleIndex;
  44. } PrefStruct;
  45.  
  46. /* internal globals for use in prefs.c only */
  47. static    Boolean            gCanSavePrefs;
  48. static    PrefStruct        thePrefs;
  49. static    long            gPrefsFilePos;
  50.  
  51. /*-----------------------------------------------------------------------------------*/
  52. /* internal stuff for prefs.c                                                        */
  53.  
  54. short OpenPrefsFile(short *prefsFileID);
  55. short SetupNewPrefsFile(short prefsFileID);
  56. void ClosePrefsFile(short prefsFileID);
  57. short GetNextPrefs(short prefsFileID);
  58. short SavePrefs(short prefsFileID);
  59. short CheckVersion(short prefsFileID);
  60. short GetFileID(void);
  61. short CheckFileID(void);
  62. short Virgin(short prefsFileID);
  63. void DefaultPrefs(void);
  64. void CopyGlobalsToPrefs(void);
  65. void CopyPrefsToGlobals(void);
  66.  
  67. void SaveThePrefs(void)
  68. /* standard procedure callable from anywhere to save prefs to disk (if possible) */
  69. {
  70.     short            prefsFileID;
  71.     
  72.     if (gCanSavePrefs)        /* if we had no errors in PreferencesInit() */
  73.     {
  74.         OpenPrefsFile(&prefsFileID);    /* open the prefs file */
  75.         CopyGlobalsToPrefs();            /* copy global variables to prefs struct */
  76.         SavePrefs(prefsFileID);            /* save prefs to disk */
  77.         ClosePrefsFile(prefsFileID);    /* close prefs file */
  78.     }
  79. }
  80.  
  81. short PreferencesInit(void)
  82. {
  83.     short            prefsFileID;
  84.     short            err;
  85.     
  86.     gCanSavePrefs=FALSE;    /* assume the worst and maybe you'll be pleasantly surprised */
  87.     err=OpenPrefsFile(&prefsFileID);    /* open prefs file (or create new one) */
  88.     if (err!=prefs_allsWell)
  89.     {
  90.         if ((err==prefs_diskReadErr) || (err==prefs_diskWriteErr) || (err==prefs_virginErr))
  91.             ClosePrefsFile(prefsFileID);    /* close & abort if error or if new prefs */
  92.         return err;
  93.     }
  94.     
  95.     err=CheckVersion(prefsFileID);        /* check prefs version */
  96.     if (err!=prefs_allsWell)
  97.     {
  98.         ClosePrefsFile(prefsFileID);
  99.         return err;
  100.     }
  101.     
  102.     GetFPos(prefsFileID, &gPrefsFilePos);
  103.     err=GetNextPrefs(prefsFileID);        /* get prefs struct from file */
  104.     if (err==prefs_noMorePrefsErr)        /* or not */
  105.         return (Virgin(prefsFileID));    /* can't find our prefs struct */
  106.         
  107.     if (err!=prefs_allsWell)            /* any other error, just abort */
  108.     {
  109.         ClosePrefsFile(prefsFileID);
  110.         return err;
  111.     }
  112.     
  113.     CopyPrefsToGlobals();                /* copy prefs struct to program globals */
  114.     ClosePrefsFile(prefsFileID);        /* close prefs file */
  115.     gCanSavePrefs=TRUE;
  116.     return prefs_allsWell;                /* piece o' cake */
  117. }
  118.  
  119. short OpenPrefsFile(short *prefsFileID)
  120. {
  121.     short            thisFile;
  122.     OSErr            isHuman;
  123.     short            vRefNum;
  124.     long            dirID;
  125.     FSSpec            prefsFile;
  126.     FInfo            prefsInfo;
  127.     Boolean            newPrefs;
  128.     unsigned char    *name=PREFS_FILE_NAME;
  129.     
  130.     newPrefs=FALSE;
  131.     /* find vRefNum and dirID of preferences folder, creating it if necessary */
  132.     isHuman=FindFolder(kOnSystemDisk, 'pref', kCreateFolder, &vRefNum, &dirID);
  133.     
  134.     if (isHuman!=noErr)        /* screwed up already?!? */
  135.         return prefs_cantOpenPrefsErr;
  136.     if (gHasFSSpecs)
  137.     {
  138.         isHuman=FSMakeFSSpec(vRefNum, dirID, name, &prefsFile);    /* make FSSpec out of it */
  139.         if (isHuman!=noErr)
  140.         {
  141.             if (isHuman==fnfErr)    /* FSSpec is valid, but prefs file does not exist */
  142.             {
  143.                 isHuman=FSpCreate(&prefsFile, CREATOR, PREFS_TYPE, 0);    /* so create it */
  144.                 if (isHuman!=noErr)                                        /* or not */
  145.                     return prefs_cantCreatePrefsErr;
  146.                 newPrefs=TRUE;        /* signal that prefs file is new */
  147.             }
  148.             else return prefs_cantOpenPrefsErr;
  149.         }
  150.         isHuman=FSpOpenDF(&prefsFile, fsRdWrPerm, &thisFile);    /* open prefs file */
  151.         *prefsFileID=thisFile;        /* store file reference number */
  152.         if (isHuman!=noErr)
  153.             return prefs_cantOpenPrefsErr;
  154.     }
  155.     else
  156.     {
  157.         /* try to open prefs file */
  158.         isHuman=HOpen(vRefNum, dirID, name, fsRdWrPerm, &thisFile);
  159.         *prefsFileID=thisFile;
  160.         if (isHuman!=noErr)
  161.         {
  162.             if (isHuman==fnfErr)    /* prefs file does not exist */
  163.             {
  164.                 /* ...so create it */
  165.                 if (HCreate(vRefNum, dirID, name, CREATOR, PREFS_TYPE)!=noErr)
  166.                     return prefs_cantCreatePrefsErr;
  167.                 prefsInfo.fdType=PREFS_TYPE;
  168.                 prefsInfo.fdCreator=CREATOR;
  169.                 prefsInfo.fdFlags=0;
  170.                 prefsInfo.fdLocation.h=prefsInfo.fdLocation.v=0;
  171.                 prefsInfo.fdFldr=0;
  172.                 
  173.                 /* set file info of newly created prefs file */
  174.                 if (HSetFInfo(vRefNum, dirID, name, &prefsInfo)!=noErr)
  175.                     return prefs_cantCreatePrefsErr;
  176.                 
  177.                 /* NOW open the prefs file */
  178.                 isHuman=HOpen(vRefNum, dirID, name, fsRdWrPerm, &thisFile);
  179.                 *prefsFileID=thisFile;        /* store file reference number */
  180.                 if (isHuman!=noErr)
  181.                     return prefs_cantOpenPrefsErr;
  182.                 newPrefs=TRUE;                /* signal that prefs file is new */
  183.             }
  184.             else return prefs_cantOpenPrefsErr;
  185.         }
  186.     }
  187.     if (newPrefs)
  188.         return SetupNewPrefsFile(*prefsFileID);        /* needs initial setup if new */
  189.     
  190.     return prefs_allsWell;
  191. }
  192.  
  193. short SetupNewPrefsFile(short prefsFileID)
  194. /* this writes the prefs version number to the newly created prefs file, so we can
  195.    tell if the prefs file was created by a later version of the program and is
  196.    therefore in a format that we don't support -- forward compatability!  what
  197.    a concept! */
  198. {
  199.     long            count;
  200.     short            temp;
  201.     
  202.     gPrefsFilePos=2L;
  203.     if (SetEOF(prefsFileID, 2L)!=noErr)    /* set length of prefs file to 2 */
  204.         return prefs_diskWriteErr;
  205.     
  206.     SetFPos(prefsFileID, 1, 0L);
  207.     temp=PREFS_HEADER_VERSION;            /* get the prefs version (hardcoded) */
  208.     count=2L;
  209.     if (FSWrite(prefsFileID, &count, &temp)!=noErr)        /* write prefs version */
  210.         return prefs_diskWriteErr;        
  211.     
  212.     return Virgin(prefsFileID);            /* be gentle; it's our first time */
  213. }
  214.  
  215. void ClosePrefsFile(short prefsFileID)
  216. {
  217.     FSClose(prefsFileID);                /* close file on disk */
  218.     FlushVol(0L, kOnSystemDisk);        /* flush volume to write out new info */
  219. }
  220.  
  221. short GetNextPrefs(short prefsFileID)
  222. {
  223.     OSErr        isHuman;
  224.     long        count;
  225.     
  226.     count=sizeof(thePrefs);
  227.     isHuman=FSRead(prefsFileID, &count, &thePrefs);        /* get next prefs struct */
  228.     if (isHuman==eofErr)    /* no more left */
  229.         return prefs_noMorePrefsErr;
  230.     if (isHuman!=noErr)        /* some other error */
  231.         return prefs_diskReadErr;
  232.     
  233.     return prefs_allsWell;
  234. }
  235.  
  236. short SavePrefs(short prefsFileID)
  237. {
  238.     long        oldEOF;
  239.     long        count;
  240.     
  241.     GetEOF(prefsFileID, &oldEOF);
  242.     if (gPrefsFilePos>=oldEOF)        /* add new prefs struct onto end of prefs file */
  243.     {
  244.         if (SetEOF(prefsFileID, oldEOF+sizeof(thePrefs))!=noErr)
  245.             return prefs_diskWriteErr;
  246.     }
  247.     
  248.     SetFPos(prefsFileID, 1, gPrefsFilePos);        /* set position inside prefs file */
  249.     count=sizeof(thePrefs);
  250.     /* write prefs struct and return appropriate error code */
  251.     return (FSWrite(prefsFileID, &count, &thePrefs)!=noErr) ?
  252.         prefs_diskWriteErr : prefs_allsWell;
  253. }
  254.  
  255. short CheckVersion(short prefsFileID)
  256. {
  257.     OSErr            isHuman;
  258.     long            count;
  259.     short            temp;
  260.     
  261.     count=2L;
  262.     isHuman=FSRead(prefsFileID, &count, &temp);        /* get prefs version */
  263.     if (isHuman!=noErr)
  264.         return prefs_diskReadErr;
  265.     if (temp>PREFS_HEADER_VERSION)                    /* too new */
  266.         return prefs_versionNotSupportedErr;
  267.     if (temp<PREFS_HEADER_VERSION)                    /* old; overwrite */
  268.         return SetupNewPrefsFile(prefsFileID);
  269.     
  270.     return prefs_allsWell;
  271. }
  272.  
  273. short Virgin(short prefsFileID)
  274. {
  275.     short            err;
  276.     
  277.     DefaultPrefs();
  278.     CopyGlobalsToPrefs();
  279.     err=SavePrefs(prefsFileID);
  280.     
  281.     return (err==prefs_allsWell) ? prefs_virginErr : err;
  282. }
  283.  
  284. void DefaultPrefs(void)
  285. {
  286.     gModuleIndex=-1;
  287.     gOnRestart=gOnShutdown=gChooseRandom=0xFF;
  288. }
  289.  
  290. void CopyGlobalsToPrefs(void)
  291. {
  292.     thePrefs.onrestart=gOnRestart;
  293.     thePrefs.onshutdown=gOnShutdown;
  294.     thePrefs.israndom=gChooseRandom;
  295.     thePrefs.unused=0x00;
  296.     thePrefs.moduleIndex=gModuleIndex;
  297. }
  298.  
  299. void CopyPrefsToGlobals(void)
  300. {
  301.     gOnRestart=thePrefs.onrestart;
  302.     gOnShutdown=thePrefs.onshutdown;
  303.     gChooseRandom=thePrefs.israndom;
  304.     gModuleIndex=thePrefs.moduleIndex;
  305. }
  306.